package cn.edu.sdu.order.backend.service.impl;

import cn.edu.sdu.order.backend.dao.UserMapper;
import cn.edu.sdu.order.backend.model.Token;
import cn.edu.sdu.order.backend.model.User;
import cn.edu.sdu.order.backend.model.UserExample;
import cn.edu.sdu.order.backend.service.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Service
@EnableScheduling
public class TokenServiceImpl implements TokenService {
    @Value("${timeout}")
    private int timeout;

    @Autowired
    private UserMapper userMapper;

    private Map<String, Token> tokenMap = new ConcurrentHashMap<>(1<<8);

    @Override
    public Token login(String workCode, String password) {
        UserExample userExample = new UserExample();
        userExample.createCriteria()
                .andUserNameEqualTo(workCode)
                .andPasswordEqualTo(password);
        List<User> users = userMapper.selectByExample(userExample);
        if(users.isEmpty()){
            throw new RuntimeException("用户不存在或者账号密码错误");
        } else {
            User user = users.get(0);
            Token token = new Token();
            token.setAccessToken(makeToken());
            token.setUserName(user.getUserName());
            token.setUserCode(user.getUserCode());
            token.setLastAction(new Date());
            token.setAvatarUrl(user.getAvatarUrl());
            tokenMap.put(token.getAccessToken(), token);
            return token;
        }
    }



    @Override
    public Token getToken(String accessToken) {
        return tokenMap.get(accessToken);
    }

    @Override
    public void logout(String accessToken) {

    }

    @Override
    public Token create() {
        Token token = new Token();
        token.setAccessToken(makeToken());
        tokenMap.put(token.getAccessToken(), token);
        return token;
    }

    @Override
    public Boolean containsToken(String acccessToken) {
        return tokenMap.get(acccessToken) != null;
    }

    private String makeToken() { // checkException
        return UUID.randomUUID().toString().replaceAll("-", "") + "";
    }

    @Scheduled(cron = "*/20 * *  * * * ")
    public void scheduled() {
        Iterator<Map.Entry<String, Token>> iterator = tokenMap.entrySet().iterator();
        Date now = new Date();
        while (iterator.hasNext()) {
            Map.Entry<String, Token> entry = iterator.next();
            if (now.getTime() - entry.getValue().getLastAction().getTime() > 60 * timeout * 1000) {
                iterator.remove();
            }
        }
    }
}
